/**
 * @widoc $.fn.initCombo
 * @namespace comp
 * @des 初始化可输入下拉框。
 * @type function
 * @param {object} opts
 * @param {string} opts.name 下拉框元素的 name 属性值，初始化完成后，会在 el 后生成 <input type="hidden" name="name"/>，以便表单取值
 * @param {Array=} opts.data 候选项键值对数组。
 * @param {object} opts.data[i] {name(文本):xx, value(值):xx}
 * @param {boolean=} opts.multiple 是否多选，默认为false，若为多选，data 中 name 需与 value 一致。// TODO 功能未测试完整
 * @param {string=} opts.txtField opts.data 数据中的文本字段名(默认为 txt)
 * @param {string=} opts.valField opts.data 数据中的值字段名(默认为 val)
 * @param {string=} opts.value 初始化时默认显示的值
 * @param {function=} opts.onChange(val) 值改变时的回调函数，参数为当前 value
 */
$.fn.initCombo = function(opts){
    var el = $(this),
        oApi,
        jqSel, jqTxt,
        txtField, valField,
        data,
        readonly;
    if(!opts.name){
        console.error('initCombo 初始化时必须传入 name!');
        return;
    }
    opts = $.extend({
        data: [],
        onChange: $.noop,
        readonly: false,
        multiple: false,// 多选 TOOD 功能未详细测试
        txtField: 'txt',
        valField: 'val'
    }, opts);
    var fSetVal = function(newVal){
        jqTxt.val(newVal);
        opts.onChange(newVal);
    };
    var fGetVal = function(){
        return jqTxt.val().trim();
    };
    var fSetDisabled = function(stat){
        readonly = stat !== false;// 不定义时设为 true
        if(readonly){
            el.addClass('wi-combo-disabled');
        }
        else{
            el.removeClass('wi-combo-disabled');
        }
        jqSel.prop('disabled', readonly);// 没有readonly状态，只能设为disabled，且通过e.preventDefault()也无法拦截弹出选项
        jqTxt.prop('disabled', readonly);
    };
    var fOnSelChange = function(){
        var newVal = jqSel.val();
        if(opts.multiple){
            jqTxt.val(newVal.join('/'));
            jqSel.val([]);// 清空选中，防止文本修改后仍被选中
        }
        else{
            jqTxt.val(jqSel.find('option[value="' + newVal + '"]').text());
            jqSel.val('-1');// 清空选中，防止文本修改后仍被选中
        }
        opts.onChange(jqTxt.val());
    };
    var fOnTxtChange = function(){
        opts.onChange(jqTxt.val());
    };
    var fReset = function(cusOpts){
        if(cusOpts){
            $.extend(opts, cusOpts);
            txtField = opts['txtField'];
            valField = opts['valField'];
            if(cusOpts.data){// 可选列表发生变化，需要重绘组件
                data = opts['data'] || [];// 暂存数据
                var str = '<input class="wi-combo-txt" type="text" name="' + opts['name'] + '" />' +
                    '<select class="wi-combo-sel">';
                for(var i = 0, item; i < data.length; i++){
                    item = data[i];
                    str += '<option value="' + item[valField] + '">' + item[txtField] + '</option>'
                }
                str += '</select>';
                el.html(str);
                jqSel = el.find('.wi-combo-sel');
                jqTxt = el.find('.wi-combo-txt');
            }
            // 若数据变更引起重绘或设置了不同的只读状态（完全匹配），处理
            if(cusOpts.data || typeof (cusOpts.readonly != 'undefined' && cusOpts.readonly !== readonly)){
                fSetDisabled(opts.readonly);
            }
            if(opts.multiple){// 多选
                jqSel.val([]);// 清空选中
            }
            else{// 单选
                jqSel.val('-1');// 清空选中
            }
            fSetVal(cusOpts.value);// 根据最新传入的选中值进行选中操作
        }
    };
    var fInit = function(){
        if(($.styleHelper.getValue(el, 'position') || 'static' ) === 'static'){// 因其中 select 采用定位，因此需将 el 设置为参照元素
            el.css('position', 'relative');
        }
        fReset(opts);
        el.addClass('wi-combo');
        jqSel.off('change.combo')
             .on('change.combo', fOnSelChange);
        jqTxt.off('change.combo');
        if(opts.onChange){
            jqTxt.on('change.combo', fOnTxtChange);
        }
        el.data('wiCombo', oApi);
    };
    oApi = {
        fSetVal: fSetVal,// 设置当前值
        fGetVal: fGetVal,// 返回当前值
        fSetDisabled: fSetDisabled// 禁用
    };
    fInit();
    return oApi;
};